package xyz.yuzegod.megawalls.spectator;

import xyz.yuzegod.megawalls.MegaWalls;
import xyz.yuzegod.megawalls.database.DataBase;
import xyz.yuzegod.megawalls.database.KeyValue;
import xyz.yuzegod.megawalls.game.GamePlayer;
import xyz.yuzegod.megawalls.stats.SQLSettings;

import java.util.HashMap;
import java.util.Map;

public class SpectatorSettings
{
    private static final Map<GamePlayer, SpectatorSettings> CACHES;
    private static DataBase database;
    private final GamePlayer player;
    private int speed;
    private boolean autoTp;
    private boolean nightVision;
    private boolean firstPerson;
    private boolean hideOther;
    private boolean fly;
    
    public SpectatorSettings(final GamePlayer player) {
        this.player = player;
        if (!SpectatorSettings.database.isValueExists("spectator_settings", SQLSettings.KV_SPECTATOR_SETTINGS, new KeyValue("uuid", player.getUuid().toString()))) {
            SpectatorSettings.database.dbInsert("spectator_settings", new KeyValue("uuid", player.getUuid().toString()).add("speed", 0).add("autoTp", 0).add("nightVision", 0).add("firstPerson", 1).add("hideOther", 0).add("fly", 0));
        }
        this.load();
    }
    
    public static SpectatorSettings get(final GamePlayer player) {
        if (SpectatorSettings.CACHES.containsKey(player)) {
            return SpectatorSettings.CACHES.get(player);
        }
        final SpectatorSettings s = new SpectatorSettings(player);
        SpectatorSettings.CACHES.put(player, s);
        return s;
    }
    
    public void load() {
        for (final KeyValue kv : SpectatorSettings.database.dbSelect("spectator_settings", SQLSettings.KV_SPECTATOR_SETTINGS, new KeyValue("uuid", this.player.getUuid().toString()))) {
            this.speed = Integer.parseInt(kv.getString("speed"));
            this.autoTp = (Integer.parseInt(kv.getString("autoTp")) == 1);
            this.nightVision = (Integer.parseInt(kv.getString("nightVision")) == 1);
            this.firstPerson = (Integer.parseInt(kv.getString("firstPerson")) == 1);
            this.hideOther = (Integer.parseInt(kv.getString("hideOther")) == 1);
            this.fly = (Integer.parseInt(kv.getString("fly")) == 1);
        }
    }
    
    public int getSpeed() {
        return this.speed;
    }
    
    public void setSpeed(final int key) {
        if (key < 0 || key > 4) {
            return;
        }
        this.speed = key;
        SpectatorSettings.database.dbUpdate("spectator_settings", new KeyValue("speed", key), new KeyValue("uuid", this.player.getUuid().toString()));
    }
    
    public boolean getOption(final Option o) {
        switch (o) {
            case AUTOTP: {
                return this.autoTp;
            }
            case NIGHTVISION: {
                return this.nightVision;
            }
            case FIRSTPERSON: {
                return this.firstPerson;
            }
            case HIDEOTHER: {
                return this.hideOther;
            }
            case FLY: {
                return this.fly;
            }
            default: {
                return false;
            }
        }
    }
    
    public void setOption(final Option o, final boolean key) {
        if (this.getOption(o) && key) {
            return;
        }
        switch (o) {
            case AUTOTP: {
                this.autoTp = key;
                SpectatorSettings.database.dbUpdate("spectator_settings", new KeyValue("autoTp", (int)(key ? 1 : 0)), new KeyValue("uuid", this.player.getUuid().toString()));
                break;
            }
            case NIGHTVISION: {
                this.nightVision = key;
                SpectatorSettings.database.dbUpdate("spectator_settings", new KeyValue("nightVision", (int)(key ? 1 : 0)), new KeyValue("uuid", this.player.getUuid().toString()));
                break;
            }
            case FIRSTPERSON: {
                this.firstPerson = key;
                SpectatorSettings.database.dbUpdate("spectator_settings", new KeyValue("firstPerson", (int)(key ? 1 : 0)), new KeyValue("uuid", this.player.getUuid().toString()));
                break;
            }
            case HIDEOTHER: {
                this.hideOther = key;
                SpectatorSettings.database.dbUpdate("spectator_settings", new KeyValue("hideOther", (int)(key ? 1 : 0)), new KeyValue("uuid", this.player.getUuid().toString()));
                break;
            }
            case FLY: {
                this.fly = key;
                SpectatorSettings.database.dbUpdate("spectator_settings", new KeyValue("fly", (int)(key ? 1 : 0)), new KeyValue("uuid", this.player.getUuid().toString()));
                break;
            }
        }
    }
    
    public GamePlayer getPlayer() {
        return this.player;
    }
    
    static {
        CACHES = new HashMap<GamePlayer, SpectatorSettings>();
        SpectatorSettings.database = MegaWalls.getInstance().getDataBase();
    }
    
    public enum Option
    {
        AUTOTP, 
        NIGHTVISION, 
        FIRSTPERSON, 
        HIDEOTHER, 
        FLY;
    }
}
